package com.mofum.msdom.excel.annotation.parser.impl;

import com.mofum.msdom.excel.annotation.ATHeaderRow;
import com.mofum.msdom.excel.annotation.ATHeaderColumn;
import com.mofum.msdom.excel.annotation.parser.AnnotationParser;
import com.mofum.msdom.excel.metadata.MPHeaderRow;
import com.mofum.msdom.excel.metadata.MPHeaderColumn;
import com.mofum.msdom.excel.metadata.MPStyle;
import com.mofum.msdom.excel.utils.ReflectUtils;
import com.mofum.msdom.excel.utils.StyleUtils;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 头部解析器
 *
 * @author 1615690513@qq.com
 * @since 2018/11/28 0028 15:00
 */
public class ATHeaderRowParser<T> implements AnnotationParser<T, MPHeaderRow> {

    public Map<Field, MPHeaderRow> parseField(T o) {

        Map<Field, MPHeaderRow> map = new HashMap<Field, MPHeaderRow>();

        Field[] fields = ReflectUtils.convertToClass(o).getDeclaredFields();

        for (Field field : fields) {

            if (field.isAnnotationPresent(ATHeaderRow.class)) {

                ATHeaderRow atHeaderRow = field.getAnnotation(ATHeaderRow.class);

                map.put(field, parse(atHeaderRow));

            }

        }

        return map;
    }

    public Map<Type, MPHeaderRow> parseType(T o) {

        Map<Type, MPHeaderRow> map = new HashMap<Type, MPHeaderRow>();

        Class<T> clazz = ReflectUtils.convertToClass(o);

        if (clazz.isAnnotationPresent(ATHeaderRow.class)) {

            ATHeaderRow atHeaderRow = clazz.getAnnotation(ATHeaderRow.class);

            map.put(clazz, parse(atHeaderRow));

        }

        return map;
    }

    public Map<Method, MPHeaderRow> parseMethod(T o) {

        Map<Method, MPHeaderRow> map = new HashMap<Method, MPHeaderRow>();

        Method[] methods = ReflectUtils.convertToClass(o).getDeclaredMethods();

        for (Method method : methods) {

            if (method.isAnnotationPresent(ATHeaderRow.class)) {

                ATHeaderRow atHeaderRow = method.getAnnotation(ATHeaderRow.class);

                map.put(method, parse(atHeaderRow));

            }

        }

        return map;
    }

    public Map<Method, List<MPHeaderRow>> parseParams(T o) {

        Map<Method, List<MPHeaderRow>> map = new HashMap<Method, List<MPHeaderRow>>();

        Method[] methods = ReflectUtils.convertToClass(o).getMethods();

        for (Method method : methods) {

            List<MPHeaderRow> list = new ArrayList<MPHeaderRow>();

            Annotation[][] parameterAnnotations = method.getParameterAnnotations();

            for (Annotation[] parameterAnnotation : parameterAnnotations) {
                for (Annotation annotation : parameterAnnotation) {
                    if (annotation instanceof ATHeaderRow) {
                        ATHeaderRow atHeaderRow = (ATHeaderRow) annotation;
                        list.add(parse(atHeaderRow));
                    }
                }
            }

            map.put(method, list);
        }

        return map;
    }


    public MPHeaderRow parse(ATHeaderRow atHeaderRow) {
        MPHeaderRow mpHeaderRow = new MPHeaderRow();
        mpHeaderRow.setIndex(atHeaderRow.index());
        mpHeaderRow.setAutoSize(atHeaderRow.autoSize());
        mpHeaderRow.setValues(atHeaderRow.values());
        mpHeaderRow.setRequired(atHeaderRow.required());

        if (atHeaderRow.columns().length == 0) {
            //数组为空则使用value值
            mpHeaderRow.setAutoSize(true);

            MPHeaderColumn[] columns = new MPHeaderColumn[atHeaderRow.values().length];
            for (int i = 0; i < atHeaderRow.values().length; i++) {
                MPHeaderColumn mpHeaderColumn = new MPHeaderColumn();
                mpHeaderColumn.setIndex(i);
                mpHeaderColumn.setValue(atHeaderRow.values()[i]);
                mpHeaderColumn.setStyles(new MPStyle[]{StyleUtils.createStyle(MPHeaderColumn.DEFAULT_STYLE)});
                columns[i] = mpHeaderColumn;
            }

            mpHeaderRow.setColumns(columns);

        } else {
            //不为空执行

            ATHeaderColumnParser<MPHeaderColumn> parser = new ATHeaderColumnParser<MPHeaderColumn>();

            List<MPHeaderColumn> list = new ArrayList<MPHeaderColumn>();

            for (ATHeaderColumn atHeaderColumn : atHeaderRow.columns()) {
                list.add(parser.parse(atHeaderColumn));
            }

            mpHeaderRow.setColumns(list.toArray(new MPHeaderColumn[]{}));

        }

        return mpHeaderRow;
    }
}
